package com.exchange.controller.app.wallet;

import com.exchange.controller.BaseController;
import com.exchange.interceptor.AppUserTokenInterceptor;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.kit.Ret;
import java.math.BigDecimal;

/**
 * 用户钱包操作
 **/
@Before({WalletValidator.class,AppUserTokenInterceptor.class})
public class WalletController extends BaseController {
	
	@Inject
	WalletService service;
	
    
    /**
     * 钱包资产明细
     */
    public void details() {
    	Ret ret = service.details(getAttr("user"));
    	renderJson(ret);
    }
    
    /**
     * 获取用户某个币种的钱包信息
     */
    public void info(String coin){
    	Ret ret = service.info(getAttr("user"), coin);
    	renderJson(ret);
    }

    /**
     * 钱包资产变化的流水
     */
    public void flow(Integer pageNumber, Integer type, String dateFrom, String dateTo) {
    	Ret ret = service.flow(getAttr("user"), pageNumber, type, dateFrom, dateTo);
    	renderJson(ret);
    }
    
    /**
     * 钱包内不同交易类型钱包相互划转
     */
    public void transfer(String coin, BigDecimal amount, String fromType, String toType) {
    	Ret ret = service.transfer(getAttr("user"), coin, amount, fromType, toType );
    	renderJson(ret);
    }
    

    /**
     * 获取数字签名
     * @param request
     * @return
     
    @RequestMapping("/signature")
    @DuplicateVerify(method = Method.WALLET_SIGNATURE)
    public ResponseData signature(@RequestBody @Valid SignDTO dto, BindingResult valid, HttpServletRequest request) {
        ResponseData data = ResponseData.ok();
        try {
            if ( valid.hasErrors()) {
                throw ExUtils.error( valid);
            }
            // 用户信息
            UserDTO user = getLoginUser( request);
            //用户token
            String token = request.getHeader( AppConst.TOKEN);
            // 验证随机串
            String nonce = Base64.encode( StrUtil.concat(Boolean.FALSE, token,
                                        StrUtil.toString( dto.getTimestamp()),
                                        ApiConst.OTC_SECRET));
            //验证数字签名
            if ( !StrUtil.equals( nonce, dto.getNonce())) {
                throw ExUtils.error( LocaleKey.SIGNATURE_NOT_NULL);
            }
            //用户详情
            UserEntity entity = userService.findUserByCondition( UserDTO.builder()
                                                                    .id( user.getId())
                                                                    .state( BizConst.BIZ_STATUS_VALID).build());
            if( ObjectUtil.isEmpty( entity)){
                throw ExUtils.error( LocaleKey.USER_NOT_FIND);
            }
            // 通过apisecret 进行加密
            StringBuffer salt = new StringBuffer();
            salt.append( token)
                        .append( entity.getApiSecret())
                        .append( dto.getNonce())
                        .append( dto.getTimestamp());
            // md5加密
            String sign = SecureUtil.md5( salt.toString());
            //
            SignVO vo = SignVO.builder()
                            .timestamp( dto.getTimestamp())
                            .signature( sign).build();
            //拼接key
            String key = StrUtil.concat(Boolean.FALSE, StrUtil.toString( user.getId()), StrUtil.UNDERLINE, token);
            //设置缓存
            redisPlugin.set(key, vo, 10000l);
            //返回数据
            data.setData( sign);
        } catch (Exception ex) {
            ExUtils.error(ex, LocaleKey.SYS_QUERY_FAILED);
        }
        return data;
    }
    /**
     * 交易所 划转到 理财平台用户
     * userId
     * coin
     * num
     * signature
     * nonce
     * account
    @RequestMapping("/exchangeToManage")
    @DuplicateVerify(method = Method.ASSETS_TRANSFER)
    public ResponseData exchangeToManage(@RequestBody BaseDTO baseDTO , HttpServletRequest request){
    	ResponseData data = ResponseData.ok();
    	try {
    		//登录用户
            UserDTO user = getLoginUser( request);
            
            //用户token
            String token = request.getHeader( AppConst.TOKEN);
            // 验证 签名
            SignVO vo = redisPlugin.get( StrUtil.concat(Boolean.FALSE,
                                            StrUtil.toString( user.getId()), StrUtil.UNDERLINE, token));
            if ( ObjectUtil.isEmpty( vo)) {
                throw ExUtils.error( LocaleKey.SIGNATURE_VALID_ERROR);
            }
            
            //拼接 key
            StringBuffer salt = new StringBuffer();
            salt.append( token)
                        .append( user.getSecret()) //api_secret
                        .append( baseDTO.getNonce())  //签名
                        .append( vo.getTimestamp());   //时间戳
            //对签名加密
            String signature = SecureUtil.md5( salt.toString());
            if ( StrUtil.isEmpty( vo.getSignature())
                        || !StrUtil.equals( vo.getSignature(), signature)
                        || !StrUtil.equals( signature, baseDTO.getSignature())
                        || !StrUtil.equals( vo.getSignature(), baseDTO.getSignature())) {
                throw ExUtils.error( LocaleKey.SIGNATURE_VALID_ERROR);
            }
            
            //币种
            if(!StrUtil.equals("ADR", baseDTO.getCoin())) {
            	throw ExUtils.error(LocaleKey.COIN_NO_TO);
            }
            //数量
            if(NumberUtil.isGreater(new BigDecimal(10), baseDTO.getNum())  ) {
            	throw ExUtils.error(LocaleKey.NUM_10);
            }
            if (baseDTO.getNum().signum() == -1) {
            	throw ExUtils.error(LocaleKey.SYS_PARAM_ERROR);
            }
            // 是否c1实名认证
            UserKycEntity kycEntity = kycService.findByCondition(BaseDTO.builder()
                    .state( BizConst.BIZ_STATUS_FAILED)
                    .userId( user.getId()).build());
            if (ObjectUtil.isEmpty( kycEntity) || BizConst.KycConst.K1_OK > kycEntity.getStep()) {
                throw ExUtils.error(LocaleKey.USER_C1_NOT_ACCESS);
            }
            //获取当前用户钱包
            UserWalletEntity wallet = userWalletService.queryUserWallet(UserWalletDTO.builder().symbol( baseDTO.getCoin()).userId( user.getId()).build());
            // 验证余额是否足够
            BigDecimal b = NumberUtil.sub(wallet.getBalance(),baseDTO.getNum());
            if (b.signum() == -1) {
            	throw ExUtils.error(LocaleKey.WALLET_INSUFFICIENT_FUNDS);
            }
            
            UserWalletDTO walletDTO =  UserWalletDTO.builder().balance(baseDTO.getNum())
                    .frozenBalance(new BigDecimal(0)).userId(user.getId()).symbol(baseDTO.getCoin()).build();
            
            ManageAndExchangeEntity entity = ManageAndExchangeEntity.builder().userId(user.getId()).num(baseDTO.getNum())
					 .coin(baseDTO.getCoin()).createTime(new Date()).type(2)
					 .operatorId(user.getId()).build();
            
            boolean boo = userWalletService.exchangeToManage(walletDTO,entity,baseDTO.getAccount());
            if(!boo) {
            	throw ExUtils.error(LocaleKey.COIN_TO_MENAGE_FAIL);
            }
    	} catch (Exception ex) {
        	ExUtils.error( ex, LocaleKey.SYS_OPERATE_FAILED);
        }
    	
        return data;
    }
    
    
    /**
     * ADS\ADR实时价格接口
     * market
     * coin
     
    @RequestMapping("/coinPrice")
    public ResponseData ranking(@RequestBody BaseDTO dto) {
        ResponseData data = ResponseData.ok();
        try {
            if(StrUtil.isEmpty( dto.getMarket())){
            	throw ExUtils.error(LocaleKey.SYS_PARAM_ERROR);
            }
            //获取交易市场对应的货币排行
            List<RankingVO> voList = CollUtil.newArrayList();
            voList = redisPlugin.hget(RedisConst.PLATFORM_RANKING, dto.getMarket());
            data.setData("币种不存在");
            for(RankingVO vo : voList) {
            	if(StrUtil.equals(vo.getSymbol(), dto.getCoin())) {
            		data.setData(vo.getClose());
            		break;
            	}
            }
        } catch (Exception ex) {
            ExUtils.error( ex, LocaleKey.SYS_QUERY_FAILED);
        }
        return data;
    }    
    
    
    //ddm-usdt兑换
    /**
     * 
     * @param dto  coin为前者,market为后者,前者要兑换成后者.num为数量.当前
     * 转换比例写死1:1
     * signature
     * nonce
     * @return
     
    @RequestMapping("/ddmConvert")
    @DuplicateVerify(method = Method.ASSETS_TRANSFER)
    public ResponseData ddmConvert(@RequestBody BaseDTO baseDTO, HttpServletRequest request) {
        ResponseData data = ResponseData.ok();
        try {
    		//登录用户
            UserDTO user = getLoginUser( request);
            
            //用户token
            String token = request.getHeader( AppConst.TOKEN);
            // 验证 签名
            SignVO vo = redisPlugin.get( StrUtil.concat(Boolean.FALSE,
                                            StrUtil.toString( user.getId()), StrUtil.UNDERLINE, token));
            if ( ObjectUtil.isEmpty( vo)) {
                throw ExUtils.error( LocaleKey.SIGNATURE_VALID_ERROR);
            }
            
            //拼接 key
            StringBuffer salt = new StringBuffer();
            salt.append( token)
                        .append( user.getSecret()) //api_secret
                        .append( baseDTO.getNonce())  //签名
                        .append( vo.getTimestamp());   //时间戳
            //对签名加密
            String signature = SecureUtil.md5( salt.toString());
            if ( StrUtil.isEmpty( vo.getSignature())
                        || !StrUtil.equals( vo.getSignature(), signature)
                        || !StrUtil.equals( signature, baseDTO.getSignature())
                        || !StrUtil.equals( vo.getSignature(), baseDTO.getSignature())) {
                throw ExUtils.error( LocaleKey.SIGNATURE_VALID_ERROR);
            }
            // 是否c1实名认证
            UserKycEntity kycEntity = kycService.findByCondition(BaseDTO.builder()
                    .state( BizConst.BIZ_STATUS_FAILED)
                    .userId( user.getId()).build());
            if (ObjectUtil.isEmpty( kycEntity) || BizConst.KycConst.K1_OK > kycEntity.getStep()) {
                throw ExUtils.error(LocaleKey.USER_C1_NOT_ACCESS);
            }
            
            //币种
            if(StrUtil.equals("DDM", baseDTO.getCoin())) {
            	if(!StrUtil.equals("USDTOMNI", baseDTO.getCoin()) && !StrUtil.equals("USDTERC20", baseDTO.getCoin())) {
            		throw ExUtils.error(LocaleKey.COIN_NO_CONVERT);
            	}
            }else if(StrUtil.equals("USDTOMNI", baseDTO.getCoin()) || StrUtil.equals("USDTERC20", baseDTO.getCoin())) {
            	if(!StrUtil.equals("DDM", baseDTO.getMarket())) {
            		throw ExUtils.error(LocaleKey.COIN_NO_CONVERT);
            	}
            }else {
            	throw ExUtils.error(LocaleKey.COIN_NO_CONVERT);
            }
            //数量
            if(NumberUtil.isGreater(new BigDecimal(10), baseDTO.getNum())  ) {
            	throw ExUtils.error(LocaleKey.NUM_10);
            }
//            if (baseDTO.getNum().signum() == -1) {
//            	throw ExUtils.error(LocaleKey.SYS_PARAM_ERROR);
//            }
            
            //获取当前用户前者钱包
            UserWalletEntity wallet = userWalletService.queryUserWallet(UserWalletDTO.builder().symbol( baseDTO.getCoin()).userId( user.getId()).build());
            // 验证余额是否足够
            BigDecimal b = NumberUtil.sub(wallet.getBalance(),baseDTO.getNum());
            if (b.signum() == -1) {
            	throw ExUtils.error(LocaleKey.WALLET_INSUFFICIENT_FUNDS);
            }
            
            UserWalletDTO walletDTO =  UserWalletDTO.builder().balance(baseDTO.getNum())
                    .frozenBalance(new BigDecimal(0)).userId(user.getId()).symbol(baseDTO.getCoin()).build();
            
            //获取当前用户后者钱包
            UserWalletDTO walletHDTO =  UserWalletDTO.builder().balance(baseDTO.getNum().negate())
                    .frozenBalance(new BigDecimal(0)).userId(user.getId()).symbol(baseDTO.getMarket()).build();
            
            DdmConvertEntity entity = DdmConvertEntity.builder().userId(user.getId()).num(baseDTO.getNum())
					 .coin(baseDTO.getCoin()).market(baseDTO.getMarket()).createTime(new Date()).scale(new BigDecimal(1))
					 .operatorId(user.getId()).build();
            
            boolean boo = userWalletService.ddmConvert(walletDTO,walletHDTO,entity,user.getAccount());
            if(!boo) {
            	throw ExUtils.error(LocaleKey.COIN_TO_MENAGE_FAIL);
            }
    	} catch (Exception ex) {
        	ExUtils.error( ex, LocaleKey.SYS_OPERATE_FAILED);
        }
    	
        return data;
    }    
    */

    
    
    
}
